<?php
include('PHP/autoinclude.php');
$database=new Database();
$search=new Search();
$recommendation = new recommendation();
set_time_limit(6000000);
//all ajax calls come here

function filterInput($input){
    return $input;
}

if(isset($_POST)){

    /* Returns the artist by name
     */
    if(isset($_POST['youtubeGetArtist'])){
       $trackName = $_POST['trackName'];
       $artistName = $_POST['youtubeGetArtist'];
       print($search->playerLink($artistName, $trackName));
    }
    
    /* Returns the album by ID
    */
    if(isset($_POST['getAlbum'])){
        $albumID = $_POST['getAlbum'];
        $album = $database->getAlbumByID($albumID, true);
        print(json_encode($album->toJSON()));
    }
    
    /* Returns an artist object, fill it if necessary
    */
    if(isset($_POST['getArtist'])){
        $artistID = $_POST['getArtist'];
        if(isset($_POST['limit'])){
            $artist = $database->getArtistByID($artistID, false, true, 5, 3);
        }
        $artist = $database->getArtistByID($artistID, false, true, null, 3);
        $flag = $database->artistHasTracks($artistID);
        if($artist && !$flag)
        {
            //FIRST TIME UPDATING PROCEDURE
            
            //As long as we don't have albums for this artist (or just a default album):
            if(count($artist->albums())<=1)
            {
                //get the albums from last.fm
                $albums=$search->getAlbumsFromWeb($artistName);
                //For every album
                foreach($albums as $album){
                    //Album cant be null (it happens sometimes ie http fail request)
                    //The artist must not already have the album
                    //Check if we already found that this album hasn't any track
                    if($album!=null && !$artist->hasAlbum($album->name()) &&!$database->checkIfEmptyAlbum($album->name(), $artist->id())){
                        $checkAlbum=$database->getAlbumByName($album->name(), $artistID);
                        //If the album is in our database, add it to its artist
                        if($checkAlbum!=null)
                        {
                            $artist->addAlbum($checkAlbum);
                        }
                        else
                        {
                            //if the album isn't already in our database, search for the tracks that are in this album
                            $tracks=$search->getSongsFromWeb($artistName, $album->name());
                            //if one or more tracks
                            if(count($tracks)!=0)
                            {
                                $album->setID($database->newAlbum($album, $artistID));
                                //loop through all tracks and add them to the album object and to the database
                                foreach($tracks as $track)
                                {
                                    //Check if known in database, act correspondingly
                                    $checkTrack=$database->getTrackByName($track->name(), $album->id());
                                    if($checkTrack==null)
                                    {
                                        $track->setID($database->newTrack($track, $album->id()));
                                        $album->addTrack($track);
                                    }
                                    else
                                    {
                                        $album->addTrack($checkTrack);
                                    }
                                    //End check if track is known
                                }
                                //End loop over all tracks from album
                                $artist->addAlbum($album);
                            }
                            else{
                                //save empty album
                                $database->addEmptyAlbum($album,$artist->id());
                            }
                            //End if-else more than one track in album
                        }
                        //End new album
                    }
                    //End check if legit album
                }
                //End 'for every album'
            }
            //End 'if(0 or less albums)'
            
            //CHECK FOR TRACKS
            $index = 0;
            if(!$database->artistHasDefaultAlbum($artistID)){
                $index = $database->artistCreateDefaultAlbum($artistID);
            }
            else{
                $index = $database->getAlbumByName('DefaultAlbum', $artistID)->id();
            }
            $tracks = $search->getTopTracks($artist->name());
            foreach($tracks as $track)
            {
                //Check this track
                if($track != null && !$artist->hasTrack($track->name()))
                {
                    //Check if track already connected to artist
                    $flag = $database->artistHasTrack($artistID, $trackName);
                    if(!$flag)
                    {
                        $database->newTrack($track, $index);
                    }
                    //end 'if($flag)'
                }
                //End 'check track'
            }
            //End 'for every track in topTracks'
        }
        //End 'if($artist)'
        $listArtist = new ListArtist();
        $listArtist->addArtist($artist);
        print(json_encode($listArtist->toJSON()));
    }
    
    /* Responds to a search query, if the query contains 'tag: ', returns relevant
     * artists for this tag, last.fm results otherwise.
    */
    if(isset($_POST['searchTerm'])){
        //The search term can be anything, an album, an artist or a track
        $searchTerm=$_POST['searchTerm'];
        $index = 0;
        /*
        if(strcmp(strtolower(substr($searchTerm, 0, 5)), 'tag: ') == 0)
        {
            $searchString = substr($searchTerm, $index);
            $searchTags = explode(" ", $searchString);
            $artists = $database->getArtistsByTagName(strtolower($searchTags[1]));
            $listArtist=new ListArtist();
            if($artists != null)
            {
                foreach($artists as $artist)
                {
                    $key=$listArtist->addArtist($artist);
                    foreach($artist->albums() as $album)
                    {
                        foreach($album->tracks() as $track)
                        {
                            $artist->addSearchTrack($track);
                        }
                    }
                    $listArtist->set($artist, $key);
                }
                print(json_encode($listArtist->toJSON()));
                return;
            }
        }*/
        $searchWords = explode(" ", $searchTerm);
        $listArtist=new ListArtist();
        //Search on the web for artists or tracks that match the search
        $result=$search->searchSong($searchTerm);
        
        for($i=0;$i<count($result);$i++)
        {
            $artistName=$result[$i]['artist'];
            $trackName=$result[$i]['track'];
            
            $artist;
            
            //retrieve the index in the artist list
            $key=$listArtist->hasArtist($artistName);
            //if the key equals -1, that means that the artist isn't yet stored in the list
            
            if($key!=-1){
               $artist=$listArtist->get($key);
               $artistID = $artist->id();
            }
            else
            {
                //print($artistName."    /t   ");
                //fetch the artist from the database
                $artist=$database->getArtistByName($artistName, 0);

                if($artist){
                                    $artistID = $artist->id();
                    $flag = $database->artistHasTracks($artistID);
                    $key=$listArtist->addArtist($artist);
                }
                if($artist && !$flag)
                {
                    //FIRST TIME UPDATING PROCEDURE
                    
                    //As long as we don't have albums for this artist (or just a default album):
                    if(count($artist->albums())<=1)
                    {
                        //get the albums from last.fm
                        $albums=$search->getAlbumsFromWeb($artistName);
                        //For every album
                        foreach($albums as $album){
                            //Album cant be null (it happens sometimes ie http fail request)
                            //The artist must not already have the album
                            //Check if we already found that this album hasn't any track
                            if($album!=null && !$artist->hasAlbum($album->name()) &&!$database->checkIfEmptyAlbum($album->name(), $artist->id())){
                                $checkAlbum=$database->getAlbumByName($album->name(), $artistID);
                                //If the album is in our database, add it to its artist
                                if($checkAlbum!=null)
                                {
                                    $artist->addAlbum($checkAlbum);
                                }
                                else
                                {
                                    //if the album isn't already in our database, search for the tracks that are in this album
                                    $tracks=$search->getSongsFromWeb($artistName, $album->name());
                                    //if one or more tracks
                                    if(count($tracks)!=0)
                                    {
                                        $album->setID($database->newAlbum($album, $artistID));
                                        //loop through all tracks and add them to the album object and to the database
                                        foreach($tracks as $track)
                                        {
                                            //Check if known in database, act correspondingly
                                            $checkTrack=$database->getTrackByName($track->name(), $album->id());
                                            if($checkTrack==null)
                                            {
                                                $track->setID($database->newTrack($track, $album->id()));
                                                $album->addTrack($track);
                                            }
                                            else
                                            {
                                                $album->addTrack($checkTrack);
                                            }
                                            //End check if track is known
                                        }
                                        //End loop over all tracks from album
                                        $artist->addAlbum($album);
                                    }
                                    else{
                                        //save empty album
                                        $database->addEmptyAlbum($album,$artist->id());
                                    }
                                    //End if-else more than one track in album
                                }
                                //End new album
                            }
                            //End check if legit album
                        }
                        //End 'for every album'
                    }
                    //End 'if(0 or less albums)'
                    
                    //CHECK FOR TRACKS
                    $index = 0;
                    if(!$database->artistHasDefaultAlbum($artistID)){
                        $index = $database->artistCreateDefaultAlbum($artistID);
                    }
                    else{
                        $index = $database->getAlbumByName('DefaultAlbum', $artistID)->id();
                    }
                    $tracks = $search->getTopTracks($artist->name());
                    foreach($tracks as $track)
                    {
                        
                        //Check this track
                        if($track != null && !$artist->hasTrack($track->name()))
                        {
                          
                            //Check if track already connected to artist
                            $flag = $database->artistHasTrack($artistID, $track->name());
                            if(!$flag)
                            {
                                
                                $database->newTrack($track, $index);
                            }
                            //end 'if($flag)'
                        }
                        //End 'check track'
                    }
                    //End 'for every track in topTracks'
                }
                //End 'if($artist)'
            }
            //End '$key == -1'
            if($artist){
                
                //search in our database for the track
                $searchTrack=$database->getTrackByName($trackName, $artistID, false);
                $album = $database->getAlbumByTrackName($trackName, $artistID);
                if($searchTrack){
                    $searchTrack->setAlbum($album);
                    if($searchTrack)
                        $artist->addSearchTrack($searchTrack);
                    $listArtist->set($artist, $key);
                }
            }
        }
        //End loop over results
        
        print(json_encode($listArtist->toJSON()));
    }
   
    /* Responds to a login-request, returns an array of relevant data
    */
    if(isset($_POST['login'])){
        $userName=$_POST['login'];
        $password=$_POST['password'];
        $in=$database->logIn($userName, $password);
        $out=array();
        if($in<=0){
            $out[0]='error';
            if($in==-1){
                $out[1]="This user doesn't exist.";
            }
            else{
                $out[1]="Username/password doesn't match.";
            }
        }
        else{
            $out[0]='';
            $user=$database->getCurrentUser();
            $out[1]=$user->userName();
            $out[2]=$in;
        }
        print(json_encode($out));
    }
    
   /* Respons to a log in check. Prints an arry with first element true or false that the user is logged in
    * Second element is the username, null if the user nog logged in
    */
    if(isset($_POST['loggedIn'])){
        $out=array();
        $user=$database->getCurrentUser();
        if($user!=null){
            $out[0]=true;
            $out[1]=$user->userName();
        }
        else{
            $out[0]=false;
            $out[1]=null;
        }
        print(json_encode($out));
    }
    /* Responds to a suggestion request. Creates a recommendation-object and returns
     * the relevant recommendations 
    */
    if(isset($_POST['suggestion'])){
        $artistID=$_POST['suggestion'];
        $rec=new Recommendation();
        $list=$rec->getTopArtists($artistID, $database->getCache('user'));
        foreach($list as $key=>$artist){
           $list[$key]->setAlbums($rec->getList($list[$key]->id()));
        }
        $out=array();
        foreach($list as $artist){
            array_push($out,$artist->toJSON());
        }
        print(json_encode($out));
    }

    /* Notifies the database that someone is listening to this track
    */
    if(isset($_POST['listening'])){
        $trackID=$_POST['listening'];
        $artistID=$_POST['artist'];
        $database->setListening($artistID, $trackID);
    }
    
    /* Creates a new user and calls database to insert him into the database
    */
    if(isset($_POST['register'])){
        $userName=$_POST['register'];
        $password=$_POST['password'];
        $email=$_POST['email'];
        $user=new User();
        $user->setEmail($email);
        $user->setUserName($userName);
        $out=$database->newUser($user, $password);
        if(is_int((int)$out)){
            $database->logIn($userName, $password);
        }
        else{
            print($out);
        }
    }
    
    /* Calls Search for information about this artist
    */
    if(isset($_POST['getArtistInfo'])){
        $artistName=$_POST['getArtistInfo'];
        $out=$search->getArtistInfo($artistName);
        print(json_encode($out));
    }
    
    /* Calls the database to process a rating, then calls Recommendation to do the same
    */
    if(isset($_POST['rate'])){
        $trackID=$_POST['rate'];
        $rating=$_POST['rating'];
        $database->rate($trackID,$rating);
        print("Recommendations: ");
        $recommendation->processRating($rating, $trackID);
    }
    
    /* Returns the known rating for this track
    */
    if(isset($_POST['getRating'])){
        $trackID=$_POST['getRating'];
        print($database->getRating($trackID));
    }

    /* Returns the top playlists for an artist (one or more)
    */
    if(isset($_POST['getTopPlaylists'])){
        $artists=$_POST['getTopPlaylists'];

        $artists=explode(';',$artists);
        $out=array();
        for($i=0;$i<count($artists);$i++){
            $list=$database->getTopPlaylist($artists[$i]);
            $json=array();
            for($j=0;$j<count($list);$j++){
                array_push($json,$list[$j]->toJSON());
            }
            array_push($out,$json);
        }
        print(json_encode($out));
    }

    /* Returns all known playlists for this user
    */
    if(isset($_POST['getAllPlaylists'])){
        $list=$database->getPlaylists();
        $out=array();
        for($i=0;$i<count($list);$i++){
            array_push($out,$list[$i]->toJSON());
        }
        print(json_encode($out));
    }
    if(isset($_POST['getPlaylistByID'])){
        $playlistID=$_POST['getPlaylistByID'];
        $playlist=$database->getPlaylistByID($playlistID);
        print(json_encode($playlist->toJSON()));
    }
    /* Saves a playlist; creates a new one or overwrites an old one
    */
    if(isset($_POST['savePlaylist'])){
        if(is_int((int)$_POST['savePlaylist'])&&!isset($_POST['namePlaylist']))
        {

            $idPlaylist = $_POST['savePlaylist'];
          
            $playlist = $database->getPlaylistByID($idPlaylist);
            $songID = $_POST['trackID'];

            $playlist->addSong($database->getTrackByID($songID),null,null);

            $database->setPlaylist($playlist);
        }
        else{
            $songs=$_POST['savePlaylist'];
            $songs=explode(';',$songs);
            $playlist=new Playlist();
            for($i=0;$i<count($songs);$i++){
                $track=new Track();
                $track->setID((int)$songs[$i]);
                $playlist->addSong($track,null,null);
            }
            $name=$_POST['namePlaylist'];
            $playlist->setName($name);
            if(isset($_POST['idPlaylist'])){
                $id=$_POST['idPlaylist'];
                $playlist->setID((int)$id);
                $database->setPlaylist($playlist);
            }
            else{
                $database->addPlaylist($playlist);
            }
        }
    }
    
    /* Returns all playlists of this user
    */
    if(isset($_POST['getPlaylistNames'])){
        $playlists=$database->getPlaylistNames();
        $out=array();
        for($i=0;$i<count($playlists);$i++){
            array_push($out,$playlists[$i]->toJSON());
        }
        print(json_encode($out));
    }
    
    /* Returns all albums of an artist
    */
    if(isset($_POST['getAllAlbumsOfArtist'])){
        $artistID=$_POST['getAllAlbumsOfArtist'];
        $artist=$database->getArtistByID($artistID, false, true, null, 0);
        print(json_encode($artist->toJSON()));
    }
    
    /* Returns a complete album by id
    */
    if(isset($_POST['getFullAlbum'])){
        $albumID=$_POST['getFullAlbum'];

        $artist=$database->getArtistByID($_POST['artistID'], false, false);
        $album=$database->getAlbumByID($albumID);

        $album->setInfo($search->getAlbumInfo($artist->name(), $album->name()));

        $out=array();
        $out[0]=$album->toJSON();
        $out[1]=$artist->toJSON();
        
        print(json_encode($out));
    }
    
    /* Returns a playlist based on an album
    */
    if(isset($_POST['albumPlaylist'])){
        $albumID=$_POST['albumPlaylist'];
        $artistID=$_POST['artistID'];
        
        $artist=$database->getArtistByID($artistID, false, false);
        $album=$database->getAlbumByID($albumID);
        $tracks=$album->songs();
        
        $playlist=new Playlist();
        $playlist->setName('(Album)'.$album->name());
        for($i=0;$i< count($tracks);$i++){
            $playlist->addSong($tracks[$i], $artist, $album);
        }
        print(json_encode($playlist->toJSON()));
    }
    
    /* Returns a collection of statistics per genre for both one user and all users
    */
    if(isset($_POST['statistics'])){
        $out=array();
        $out['global'] = $database->getGlobalStatCount();
        $personal = $database->getPersonalStatCount();
        if($personal==null){
            $out['personal'] = 'error';
        }
        else{
            $out['personal'] = $personal;
        }
        print(json_encode($out));
    }
    if(isset($_POST['addTracktoPlay'])){
        $playlistID=$_POST['addTracktoPlay'];
        $newTrackID=$_POST['trackID'];
        $newTrack=new Track();
        $newTrack->setID($newTrackID);
        $playlist=$database->getPlaylistByID($playListID);
        $playlist->addSong($newTrack, null, null);
        $database->setPlaylist($playlist);
    }
}
?>
